WSM 俺自身がDHCPサーバーとなることだ

問題文

中古のマシン(計算機X)を購入したので、早速環境構築だ!って思ったがまともに稼働しているインターフェイスがなく、唯一8P8CジャックのあるNICだけが動作していた! 購入時についてきた元オーナーの手紙を読むと、どうやらそのインターフェイスでsshdとdhcpv4クライアントサービスが稼働しているとのこと。

あいにく、現在使用中のL2スイッチには空きポートがない。代わりに直接ホストマシンとそのマシンをLANケーブルをつないだので、ホストマシン自身がDHCPサーバーとなってその計算機にIPアドレスを割り振り、その計算機上で作業をできるようにしよう。

DHCPサーバーのサービスにはisc-dhcp-serverなどがある。

トポロジ図

前提条件

  • ホストマシン(wsmhost)の外部へのインターフェイス(eth1)はdhcpを用いたネットワーク設定であること。
  • ホストマシンの再起動後、計算機Xとの疎通ができなくても良い
  • 計算機Xから外のインターネットへの通信はできなくても良い

初期状態

  • 計算機Xにipアドレスが割り当てられていない。

終了状態

  • 計算機Xにipアドレスが割り当てられており、疎通ができる。
  • この状態の永続化は求めない。(再起動して、計算機Xとの疎通ができなくなってもよい)

初期状態のマシンの設定(抜粋)

ホストマシンのnetplan設定 /etc/netplan/99-netcfg.yaml

network:
  ethernets:
    eth1:
      dhcp4: true
  renderer: NetworkManager
  version: 2

ホストマシンのNetworkManager設定 /etc/NetworkManager/system-connections/netplan-eth0.nmconnection

[connection]
id=netplan-eth0
uuid=626dd384-8b3d-3690-9511-192b2c79b3fd
type=ethernet
interface-name=eth0
permissions=
timestamp=1677342394

[ethernet]
mac-address-blacklist=
wake-on-lan=0

[ipv4]
address1=10.0.0.1/24
dhcp-timeout=2147483647
dns-search=
method=auto

[ipv6]
addr-gen-mode=eui64
dns-search=
method=ignore

[proxy]

ホストマシンのDHCPサーバーの設定

/etc/dhcp/dhcpd.conf

subnet 10.0.0.0 netmask 255.255.255.0 {
  range 10.0.0.128 10.0.0.254;
  option routers 10.0.0.1;
  option subnet-mask 255.255.255.0;
  option broadcast-address 10.0.0.255;
  default-lease-time 600;
  max-lease-time 7200;
}

/etc/default/isc-dhcp-server

INTERFACESv4="eth0"
INTERFACESv6=""

解説

この問題は、ホストマシンでDHCPサーバーを建てて、LANケーブルで直接つながっている別のマシンにip情報を渡す問題となっています。しかし、ホストマシンはいくつかトラブルを抱えており、NetplanとNetworkManagerの設定が混在している、初期状態ではDHCPサーバーを動かすインターフェースでDHCPクライアントが稼働している、がありました。クライアントによっては自身のDHCPサーバーの情報を得てしまいます。今回のDHCPクライアントはdhclientを用いており、これは自身のDHCPサーバーの情報を獲得します。これによって、ネットワーク設定に競合が生ずる(ゲートウェイ情報など)ため、回避する必要があります。今回の環境では、メトリック差から自身のDHCPサーバーの方を優先する環境にしていたため、ネットワーク情報が上書きされ、障害が生じます。

この事象を観測する方法は、systemctl status NetworkManager などを使って、余分に動いてるdhclientの情報から推測できます。(以下は例)

● NetworkManager.service - Network Manager
     Loaded: loaded (/lib/systemd/system/NetworkManager.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2023-03-03 20:14:48 JST; 2 days ago
       Docs: man:NetworkManager(8)
   Main PID: 277 (NetworkManager)
      Tasks: 11 (limit: 1111)
     Memory: 18.8M
     CGroup: /system.slice/NetworkManager.service
             ├─277 /usr/sbin/NetworkManager --no-daemon
             ├─392 /sbin/dhclient -d -q -sf /usr/lib/NetworkManager/nm-dhcp-helper -pf /run/NetworkManager/dhclient-eth0.pid -lf /var/lib/NetworkManager/dhclient-626dd384-8b3d-3690-9511-192b2c79b3fd-eth0.lease -cf /var/lib/NetworkManager/dhclient-eth0.conf eth0
             └─394 /sbin/dhclient -d -q -sf /usr/lib/NetworkManager/nm-dhcp-helper -pf /run/NetworkManager/dhclient-eth1.pid -lf /var/lib/NetworkManager/dhclient-8bf25856-ca0b-388e-823c-b898666ab9d2-eth1.lease -cf /var/lib/NetworkManager/dhclient-eth1.conf eth1

この事象を回避する方法は多く考えられますが、簡単な例を上げるならばNetplanを通じて、

  • ホストマシンのそのインターフェースでのDHCPクライアントを無効にする
  • ホストマシンのDHCPサーバーの設定からゲートウェイ情報を外す
  • ホストマシンのそのインターフェースでのメトリック値を増やす

などがあります。

続いて、計算機Xが獲得したIPを確認するため、DHCPサーバーのログを確認しましょう。
例えば、isc-dhcp-serverならば、journalctlsystemctl statusなどからログを確認できます。また、/var/lib/dhcpd/dhcpd.leasesファイルからリース情報を得ることでも確認できます。
取得IPを見つけたら、そのIPを用いてpingなどで疎通を確認しましょう。

なお、コンテスト環境の特性上、外部からのSSH通信による操作になっておりますが、ゲートウェイが書き換えられると通信が確立できなくなり、ホストマシンから締め出されてしまいます。

採点基準

  • とにかく計算機Xにipアドレスを与えて、ホストマシンから通信できた 50%
  • 上記に加えて前提条件が守られていた 50%